home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- Multiprint prints a file as multiple pages condensed on a single printed
- page. It is called as follows:
-
- multiprint [-f bodyfont] [-F titlefont] [-p <factor>] [-P printer] file(s)
-
- also -1 is a synonym for -p 1, -2 for -p 2, .. -9 for -p 9.
-
- Multiprint prints a square array of pages <factor> on a side. If <factor>
- is 2, 4 pages are printed, if 3, 9 are printed, etc. Any positive integer
- value is valid, although it is pretty hard to read if <factor> is larger
- than 3.
-
- The program is probably not the most robust in the world, and currently
- assumes that your lp command prints to an Apple laser writer. All the source
- is in multiprint.c, and you are welcome to hack on it. The stuff printed by
- the routine printheaderstuff() can easily be modified to change the
- appearance of all the printed pages. The header data assumes that an 8 1/2
- by 11 inch page is being printed, with all the actual text at least 1/2 inch
- from the boundary.
-
- The files cz4 and cz9 are simple shell scripts that print a list of files 4
- or 9 pages at a time, respectively.
-
- I assume everything will work on any machine, although I have only tried it
- on a 3000.
-
- -- Tom Davis, Silicon Graphics
-
- Addendum:
-
- Added command line argument parsing.
- Made sure temporary files are unique.
-
- -- Greg Couch, U.C. Berkeley
-
- (6/10/88) Modified the PostScript output so that the printing will
- be much more efficient.
-
- -- Tom Davis
-
- (7/6/88) Use Adobe meta-comments for pages and prologs so filters like
- psrev can reverse pages only if needed (no longer uses temporary files).
- Improved BSD lpr vs. Sys V lp support.
-
- -- Greg Couch, U.C. San Francisco
-
- Todo:
-
- When using proportional fonts need tabs to go to fixed positions.
-
- */
-
- #include <stdio.h>
-
- extern char *ctime(), *getenv();
- extern long time();
- extern int optind;
- extern char *optarg;
-
- int pagefactor;
- char *printer;
- char *bodyfont, *titlefont;
- int pages_by_row;
-
- int line;
- char *timestr;
- FILE *printfile, *outputfile;
- int ordinal;
- # ifdef BSDLPR
- int no_burst;
- # endif
- int to_stdout;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- long clock;
- int i;
- char buf[100];
- int c;
-
- /* defaults */
- pagefactor = 2;
- printer = 0;
- # ifdef BSDLPR
- if ((printer = getenv("PRINTER")) == NULL)
- # else
- if ((printer = getenv("LPDEST")) == NULL)
- # endif
- titlefont = "Courier-Bold";
- bodyfont = "Courier";
- pages_by_row = 0;
-
- /* parse arguments */
- while ((c = getopt(argc, argv,
- # ifdef BSDLPR
- "123456789f:F:p:P:rsh"
- # else
- "123456789f:F:p:d:rs"
- # endif
- )) != EOF) {
- switch (c) {
-
- case '1': case '2': case '3':
- case '4': case '5': case '6':
- case '7': case '8': case '9':
- pagefactor = c - '0';
- break;
-
- case 'f':
- bodyfont = optarg;
- break;
-
- case 'F':
- titlefont = optarg;
- break;
-
- case 'p':
- pagefactor = atoi(optarg);
- if (pagefactor < 1)
- pagefactor = 1;
- break;
-
- # ifdef BSDLPR
- case 'P':
- # else
- case 'd':
- # endif
- printer = optarg;
- break;
-
- case 'r':
- pages_by_row = 1;
- break;
-
- # ifdef BSDLPR
- case 'h':
- no_burst = 1;
- break;
- # endif
-
- case 's':
- to_stdout = 1;
- break;
-
- default:
- (void) fprintf(stderr, "usage: %s [options] [files(s)]\n",
- argv[0]);
- (void) fprintf(stderr, "options: (defaults)\n");
- (void) fprintf(stderr, "\t-p <page factor>\t(2)\n");
- # ifdef BSDLPR
- (void) fprintf(stderr, "\t-P <postscript printer>\t(PostScript)\n");
- (void) fprintf(stderr, "\t-h\tsupress printing of burst page\n");
- # else
- (void) fprintf(stderr, "\t-d <postscript printer>\t(PostScript)\n");
- # endif
- (void) fprintf(stderr, "\t-f <text font>\t\t(Courier)\n");
- (void) fprintf(stderr, "\t-F <title font>\t\t(Courier-Bold)\n");
- (void) fprintf(stderr, "\t-s\toutput to stdout\t\t(spool)\n");
- (void) fprintf(stderr, "\t-r\toutput pages in row order\n");
- (void) fprintf(stderr, "\t-1\tis the same as -p1\n");
- (void) fprintf(stderr, "\t-2\tis the same as -p2\n");
- (void) fprintf(stderr, "\t...\n");
- (void) fprintf(stderr, "\t-9\tis the same as -p9\n");
- return 1;
- }
- }
-
- clock = time((long *) 0);
- timestr = ctime(&clock);
- timestr[strlen(timestr) - 1] = '\0'; /* zap trailing newline */
-
- if (to_stdout)
- outputfile = stdout;
- else {
- # ifdef BSDLPR
- if(printer)
- (void) sprintf(buf, "lpr%s -P%s", no_burst ? " -h" : "", printer);
- else
- (void) sprintf(buf, "lpr%s ", no_burst ? " -h" : "");
- if ((outputfile = popen(buf, "w")) == NULL) {
- (void) fprintf(stderr, "unable to execute lpr command\n");
- return 1;
- }
- # else
- if(printer)
- (void) sprintf(buf, "lp -d%s -o\"duplex 1\"", printer);
- else
- (void) sprintf(buf, "lp -o\"duplex 1\"");
- if ((outputfile = popen(buf, "w")) == NULL) {
- (void) fprintf(stderr, "unable to execute lp command\n");
- return 1;
- }
- # endif
- }
-
- printheaderstuff();
-
- if (argc == optind) {
- printfile = stdin;
- printnextfile("stdin");
- } else {
- for (i = optind; i < argc; i++) {
- if ((printfile = fopen(argv[i], "r")) == NULL) {
- (void) fprintf(stderr, "couldn't open %s\n", argv[i]);
- continue;
- }
- printnextfile(argv[i]);
- (void) fclose(printfile);
- }
- }
-
- printtrailerstuff();
-
- if (!to_stdout)
- (void) pclose(outputfile);
- return 0;
- }
-
- printnextfile(title)
- char *title;
- {
- int row, col;
- long pagenumber = 1;
-
- while (1) {
- ordinal += 1;
- (void) fprintf(outputfile, "%%%%Page: ? %d\n", ordinal);
- if (pages_by_row) {
- for (row = 0; row < pagefactor; row++)
- for (col = 0; col < pagefactor; col++)
- if (printpage(row, col, title, pagenumber++))
- return;
- } else {
- for (col = 0; col < pagefactor; col++)
- for (row = 0; row < pagefactor; row++)
- if (printpage(row, col, title, pagenumber++))
- return;
- }
- (void) fprintf(outputfile, "showpage\n");
- }
- }
-
- printpage(row, col, title, pagenumber)
- int row, col;
- char *title;
- long pagenumber;
- {
- char buffer[BUFSIZ];
- char outbuf[BUFSIZ];
- static int insideline = 0;
- static int ordinal = 1;
-
- (void) fprintf(outputfile, "gsave\n");
- (void) fprintf(outputfile, "%g %g translate\n",
- 72.0*(.69+col*7.5/((float) pagefactor)),
- 72.0*(.25+(pagefactor-row-1)*10.5/((float) pagefactor)));
- (void) fprintf(outputfile, "%g %g scale\n",
- 1.0/((float) pagefactor)/1.17,
- 1.0/((float) pagefactor)/1.08);
- (void) fprintf(outputfile, "outline\n");
-
- (void) fprintf(outputfile, "/%s findfont\n", titlefont);
- (void) fprintf(outputfile, "16 scalefont\n");
- (void) fprintf(outputfile, "setfont\n");
-
- (void) fprintf(outputfile, "(%s) 36 770 ms\n", title);
- #if 0
- (void) fprintf(outputfile, "(%s) 180 10 ms\n", timestr);
- #endif
- (void) fprintf(outputfile, "(Page %ld) 515 770 ms\n",
- pagenumber++);
-
- (void) fprintf(outputfile, "/%s findfont\n", bodyfont);
- (void) fprintf(outputfile, "10.8 scalefont\n");
- (void) fprintf(outputfile, "setfont\n");
-
- (void) fprintf(outputfile, "36 756 M\n");
- line = 0;
- while (line < 66) {
- if (insideline == 0) {
- if (fgets(buffer, BUFSIZ, printfile) == NULL) {
- (void) fprintf(outputfile, "grestore\n");
- (void) fprintf(outputfile, "showpage\n");
- return 1;
- }
- }
- insideline = copyline(buffer, outbuf);
- (void) fprintf(outputfile, "(%s) ns\n", outbuf);
- line++;
- }
- (void) fprintf(outputfile, "grestore\n");
- return 0;
- }
-
- copyline(buffer, outbuf)
- char *buffer, *outbuf;
- {
- static int bufcount = 0;
- int charcount;
-
- charcount = 0;
- while (charcount < 80) {
- switch(buffer[bufcount]) {
- case '\f':
- line = 66;
- *outbuf = 0;
- bufcount = 0;
- return 0;
- case '\t':
- bufcount++;
- *outbuf++ = ' ';
- charcount++;
- while (charcount & 7) {
- *outbuf++ = ' ';
- charcount++;
- }
- charcount--;
- break;
- case '\\':
- *outbuf++ = '\\';
- *outbuf++ = '\\';
- bufcount++;
- break;
- case '(':
- *outbuf++ = '\\';
- *outbuf++ = '(';
- bufcount++;
- break;
- case ')':
- *outbuf++ = '\\';
- *outbuf++ = ')';
- bufcount++;
- break;
- case '\n':
- *outbuf = 0;
- bufcount = 0;
- return 0;
- break;
- default:
- if (buffer[bufcount] < ' ') {
- *outbuf++ = '^';
- *outbuf++ = 'A' + buffer[bufcount++];
- } else
- *outbuf++ = buffer[bufcount++];
- break;
- }
- *outbuf = 0;
- charcount++;
- }
- *outbuf = 0;
- return 1;
- }
-
- printheaderstuff()
- {
- (void) fprintf(outputfile, "%%!PS-Adobe-1.0\n");
- (void) fprintf(outputfile, "%%%%Pages: (atend)\n");
- (void) fprintf(outputfile, "%%%%DocumentFonts: %s %s\n", titlefont,
- bodyfont);
- (void) fprintf(outputfile, "%%%%CreationDate: %s\n", timestr);
- (void) fprintf(outputfile, "%%%%EndComments\n");
- (void) fprintf(outputfile, "/%s findfont\n", bodyfont);
- (void) fprintf(outputfile, "10.8 scalefont\n");
- (void) fprintf(outputfile, "setfont\n");
- (void) fprintf(outputfile, "/ns\n");
- (void) fprintf(outputfile, " { currentpoint exch pop\n");
- (void) fprintf(outputfile, " 11.2 sub 36 exch moveto show} bind def\n");
- (void) fprintf(outputfile, "/ms { moveto show } bind def\n");
- (void) fprintf(outputfile, "/M /moveto load def\n");
- (void) fprintf(outputfile, "/L /lineto load def\n");
- (void) fprintf(outputfile, "/outline\n");
- (void) fprintf(outputfile, " {\n");
- (void) fprintf(outputfile, " .1 setlinewidth\n");
- (void) fprintf(outputfile, " 0.8 setgray\n");
- (void) fprintf(outputfile, " gsave\n");
- (void) fprintf(outputfile, " 7.2 -7.2 translate\n");
- (void) fprintf(outputfile, " newpath\n");
- (void) fprintf(outputfile, " 0 0 M\n");
- (void) fprintf(outputfile, " 0 792 L\n");
- (void) fprintf(outputfile, " 612 792 L\n");
- (void) fprintf(outputfile, " 612 0 L\n");
- (void) fprintf(outputfile, " closepath\n");
- (void) fprintf(outputfile, " fill\n");
- (void) fprintf(outputfile, " grestore\n");
- (void) fprintf(outputfile, " 1.0 setgray\n");
- (void) fprintf(outputfile, " newpath\n");
- (void) fprintf(outputfile, " 0 0 M\n");
- (void) fprintf(outputfile, " 0 792 L\n");
- (void) fprintf(outputfile, " 612 792 L\n");
- (void) fprintf(outputfile, " 612 0 L\n");
- (void) fprintf(outputfile, " closepath\n");
- (void) fprintf(outputfile, " gsave fill grestore\n");
- (void) fprintf(outputfile, " 0.0 setgray\n");
- (void) fprintf(outputfile, " stroke\n");
- (void) fprintf(outputfile, " } bind def\n");
- (void) fprintf(outputfile, "%%%%EndProlog\n");
- }
- printtrailerstuff()
- {
- (void) fprintf(outputfile, "%%%%Pages: %d\n", ordinal);
- }
-